/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023.
 * Description: fast svc support
 * Author: yingelin <yingelin@huawei.com>
 * Create: 2023-04-11
 */

#include <internal/rtos_fast_svc.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/hal/fast_svc.h>

typedef void (*fast_svc_handler_noctx_t)(void);
unsigned long fast_svc_handler_ctx_default(unsigned long arg0,
	unsigned long arg1, unsigned long arg2,
	unsigned long arg3, unsigned long arg4)
{
	return 0;
}

static DEFINE_SPINLOCK(fast_svc_lock);

fast_svc_handler_noctx_t fast_svc_handler_noctx = fast_svc_handler_noctx_default;
fast_svc_handler_ctx_t fast_svc_handler_ctx = fast_svc_handler_ctx_default;

int register_fast_svc_handler_ctx(fast_svc_handler_ctx_t func)
{
	if (spin_trylock(&fast_svc_lock)) {
		if (func == NULL) {
			spin_unlock(&fast_svc_lock);
			pr_err("fast_svc_handler_ctx can not be NULL\n");
			return -EINVAL;
		}
		fast_svc_handler_ctx = func;
		pr_err("fast_svc_handler_ctx is registered successfully\n");
		spin_unlock(&fast_svc_lock);
		return 0;
	}
	return -EBUSY;
}
EXPORT_SYMBOL_NS(register_fast_svc_handler_ctx, HW_RTOS_NS);

int unregister_fast_svc_handler_ctx(void)
{
	if (spin_trylock(&fast_svc_lock)) {
		if (fast_svc_handler_ctx != fast_svc_handler_ctx_default)
			fast_svc_handler_ctx = fast_svc_handler_ctx_default;
		else
			pr_err("fast_svc_handler_ctx is not registered\n");
		spin_unlock(&fast_svc_lock);
		return 0;
	}
	return -EBUSY;
}
EXPORT_SYMBOL_NS(unregister_fast_svc_handler_ctx, HW_RTOS_NS);
